<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="content-type" content="text/html" charset="utf-8"/>
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"/>
    <meta http-equiv="X-UA-Compatible" content="ie=edge"/>
    <title>Title</title>
    <link rel="stylesheet" href="lib/font-awesome/css/font-awesome.css">
    <link rel="stylesheet" href="lib/element-ui/index.css">
    <link rel="stylesheet" href="css/cities.css">
</head>
<body style="padding: 66px;">
<div id="app" class="main-wrapper">
    <cities @confirm="cityChanged" :visible.sync="citySelectVisible" :provinces="provinces" :check-all-city="checkAll"></cities>

    <el-button type="primary" icon="el-icon-success" @click="show">确定</el-button>
    <el-button type="primary" icon="el-icon-success" @click="clear">清空</el-button>
    <div v-show="provinces.length > 0">
        <div v-for="province in provinces">
            {{province.name}}
            <hr/>
            <span v-for="city in province.cities">
                {{city.name}}
            </span>
        </div>
    </div>
</div>

<template class="cities-template">
    <el-dialog title="城市选择" :modal-append-to-body="false"
               top="5vh"
               :visible.sync="dialogVisible"
               :before-close="handleClose"
               width="80%">
        <div class="city-component">
            <header class="cc-header">
                <el-form :inline="true" :model="searchForm" @submit.native.prevent>
                    <el-form-item label="">
                        <el-input placeholder="请输入内容" v-model="searchForm.keyword" autocomplete clearable maxlength="10" show-word-limit @keyup.enter.native="search"></el-input>
                    </el-form-item>
                    <el-form-item>
                        <el-button type="primary" icon="el-icon-search" @click="search">搜索</el-button>
                        <div class="cc-history-wrapper">
                            <div class="cc-history no-select">
                                <div class="cc-history-keyword" @click="searchHistory(keyword)" type="info" v-for="(keyword, k_index) in history" :key="k_index">{{keyword}}</div>
                            </div>
                        </div>
                    </el-form-item>
                </el-form>
            </header>
            <section class="cc-content">
                <div class="cc-all">
                    <el-checkbox class="cc-check-all" v-model="checkAll" @change="handleCheckAllChange">
                        全国
                    </el-checkbox>
                </div>
                <ul class="cc-main">
                    <li class="cc-group" v-for="group in groups" :key="group.key" :class='[group.isHot ? "hot" : ""]'>
                        <div class="cc-group-title" ref="groupTitle">
                            {{group.key}}
                        </div>
                        <div class="cc-province-wrapper">
                            <div class="cc-province" v-for="province in group.provinces">
                                <div class="cc-province-title">
                                    <el-checkbox :indeterminate="province.isIndeterminate" v-model="province.checkAll" @change="handleCheckedProvinceChange(province)">
                                        <span class="cc-checkbox-label" ref="provinceTitle">{{province.name}}</span>
                                    </el-checkbox>
                                </div>
                                <el-checkbox-group class="cc-cities-wrapper" v-model="province.checkedCities" @change="handleCheckedCitiesChange(province)">
                                    <div class="cc-city-wrapper" v-for="city in province.cities">
                                        <el-checkbox class="cc-city" :label="city" :key="city.id">
                                            <span ref="city" class="cc-checkbox-label">{{city.name}}</span>
                                        </el-checkbox>
                                    </div>
                                </el-checkbox-group>
                            </div>
                        </div>
                    </li>
                </ul>
            </section>
            <footer class="cc-footer">
                <el-button type="primary" icon="el-icon-success" @click="confirm">确定</el-button>
                <el-button type="default" icon="el-icon-error" @click="cancel">取消</el-button>
            </footer>
        </div>
    </el-dialog>
</template>
<script src="lib/vue.js"></script>
<script src="lib/axios.js"></script>
<script src="lib/jquery-3.5.1.js"></script>
<script src="lib/element-ui/index.js"></script>
<script src="js/common/cache.js"></script>
<script src="js/service/api-data.js"></script>
<script>
    const citySelectKey = 'city-select-key';
    const citySelectCache = new ArrayCache(citySelectKey, 4);
    const citySelectUrl = '/service/json/province.json';
    //const citySelectUrl = '/Api/KeyValue/GetProvinceGroups';
    const cities = {
        template: $('.cities-template').html(),
        props: {
            provinces: {
                type: Array,
                default: []
            },
            checkAllCity: {
                type: Boolean,
                default: false
            },
            visible: {
                type: Boolean,
                default: false
            }
        },
        data() {
            return {
                groups: [],
                hotGroup: [],
                checkAll: false,//全国
                searchForm: {
                    keyword: '云南'
                },
                history: [],
                dialogVisible: false,
            }
        },
        watch: {
            visible(val) {
                this.inDialogVisible(val);
            },
            checkAllCity (val) {
                this.inCheckAllCity(val);
            },
            provinces(val) {
                this.inProvince(val);
            }
        },
        async mounted() {
            this.history = citySelectCache.get();
            this.inDialogVisible(this.visible);
            await this.getData();
            this.inCheckAllCity(this.checkAllCity);
            this.inProvince(this.provinces);
        },
        methods: {
            confirm() {
                //let checkedCities = [];
                //checkedCities = checkedCities.concat(province.checkedCities)

                let checkedProvinces = [];
                this.groups.map(group => {
                    group.provinces.map(province => {
                        if (province.checkedCities && province.checkedCities.length > 0) {
                            checkedProvinces.push(this.getCheckedProvince(province))
                        }
                    })
                });

                this.$emit('update:checkAllCity', this.checkAll);
                this.$emit('update:provinces', checkedProvinces);
                this.$emit('confirm', checkedProvinces, this.checkAll);
                this.outVisible(false);
            },
            getCheckedProvince(province) {
                return {
                    id: province.id,
                    name: province.name,
                    cities: province.checkedCities
                };
            },
            handleClose() {
                this.outVisible(false);
            },
            inCheckAllCity(checkAll) {
                this.checkAll = checkAll;
            },
            inProvince(inProvinces) {
                inProvinces = inProvinces || [];

                this.groups.map(group => {
                    group.provinces.map(province => {
                        province.checkAll = false;
                        province.isIndeterminate = false;
                        province.checkedCities = [];
                        inProvinces.map(inProvince => {
                            if (inProvince.id === province.id && inProvince.cities && province.cities.length > 0) {
                                province.checkedCities = inProvince.cities;
                                province.checkAll = province.cities.length === province.checkedCities.length;
                                province.isIndeterminate = !province.checkAll;
                            }
                        })
                    });
                })
            },
            inDialogVisible(visible) {
                this.dialogVisible = visible;
            },
            outVisible(visible) {
                this.$emit('update:visible', visible);
            },
            cancel() {
                this.$emit('cancel');
                this.outVisible(false);
            },
            searchHistory(keyword) {
                this.searchForm.keyword = keyword;
                this.search();
            },
            search() {
                let keyword = this.searchForm.keyword.toUpperCase();
                if (!keyword) $('ul.main').scrollTop(0);

                let $refs = this.$refs;
                //console.log('search', $refs)
                //搜索城市
                let success = this.searchCity($refs.city, keyword);
                if (!success) {
                    //搜索分组名称
                    success = this.searchGroupTitle($refs.groupTitle, keyword);
                }
                if (!success) {
                    //搜索省名称
                    success = this.searchProvinceTitle($refs.provinceTitle, keyword);
                }
                if (!success) {
                    //无结果
                } else {
                    this.history = citySelectCache.setOne(keyword);
                }
            },
            searchGroupTitle(groupRefs, keyword) {
                let len = groupRefs.length;
                for (let i = 0; i < len; i++) {
                    let ref = groupRefs[i], el = ref;
                    if (el && el.innerText === keyword) {
                        return this.setActiveKeyword(el);
                    }
                }
                return false;
            },
            searchProvinceTitle(provinceRefs, keyword) {
                let len = provinceRefs.length;
                for (let i = 0; i < len; i++) {
                    let ref = provinceRefs[i], el = ref;
                    if (el && el.innerText === keyword) {
                        return this.setActiveKeyword(el);
                    }
                }
                return false;
            },
            searchCity(cityRefs, keyword) {
                let len = cityRefs.length;
                for (let i = 0; i < len; i++) {
                    let ref = cityRefs[i], el = ref; //element-ui component
                    if (el && el.innerText === keyword) {
                        return this.setActiveKeyword(el);
                    }
                }
                return false;
            },
            setActiveKeyword(el) {
                //console.log('el', el)
                let $el = $(el).addClass('active');
                setTimeout(() => {
                    $el.removeClass('active')
                }, 5000);
                el.scrollIntoView({
                    behavior: 'smooth',
                    block: 'center',
                });
                return true;
            },
            getData() {
                $.get('/service/json/province.json', (resp) => {
                    console.log('get data', resp);
                    let groups = resp.groups;
                    let hotGroup = resp.hotGroup;

                    groups.map(group => {
                        this.setGroup(group);
                    });
                    this.setGroup(hotGroup);
                    hotGroup.isHot = true;
                    groups.unshift(hotGroup);
                    this.groups = groups;
                    this.hotGroup = hotGroup;
                })
            },
            setGroup(group) {
                group = group || {};
                group.checked = false;
                group.provinces = group.provinces || [];
                group.provinces.map(province => {
                    province.checkAll = false;
                    province.isIndeterminate = false;
                    province.checkedCities = province.checkAll ? province.cities : [];
                })
            },
            handleCheckAllChange(value) {
                //选择全国
                //无论是否选中, 都清空所有下属选项
                this.groups.map(group => {
                    this.setGroup(group);
                });
            },
            handleCheckedProvinceChange(province) {
                //取消选中全国
                if (this.checkAll) {
                    this.checkAll = false;
                }
                //console.log('handleCheckAllChange', province);
                province.isIndeterminate = false;
                province.checkedCities = province.checkAll ? province.cities : [];
            },
            handleCheckedCitiesChange(province) {
                //取消选中全国
                if (this.checkAll) {
                    this.checkAll = false;
                }
                //console.log('handleCheckedCitiesChange', province);
                let checkedCount = province.checkedCities.length;
                province.checkAll = checkedCount === province.cities.length;
                province.isIndeterminate = checkedCount > 0 && checkedCount < province.cities.length;
            }
        },
    };
    const app = new Vue({
        el: "#app",
        components: {cities},
        data: {
            citySelectVisible: false,
            provinces: [],
            checkAll: false
        },
        methods: {
            cityChanged(provinces, checkAll) {
                console.log('cityChanged', provinces, checkAll)
                this.provinces = provinces;
                this.checkAll = checkAll;
            },
            show() {
                this.citySelectVisible = true;
            },
            clear() {
                this.provinces = [];
                this.checkAll = false;
            }
        }
    })

</script>
</body>
</html>